#include "gtest/gtest.h"
#include "viml/compiler.h"
#include "viml/vm.h"

using namespace viml;

class FunctionTest : public ::testing::Test {
protected:
    Compiler compiler;
    VM vm;
    
    Value execute_source(const std::string& source) {
        auto bytecode = compiler.compile(source, "<test>");
        return vm.execute(bytecode);
    }
};

// 测试基本函数定义和调用
TEST_F(FunctionTest, BasicFunction) {
    std::string source = R"(
        function Add(a, b)
            return a + b
        endfunction
        
        let result = Add(5, 3)
    )";
    
    Value result = execute_source(source);
    
    // 检查全局变量result的值
    EXPECT_TRUE(vm.has_global("result"));
    Value result_val = vm.get_global("result");
    EXPECT_TRUE(result_val.is_number());
    EXPECT_EQ(result_val.as_number(), 8.0);
}

// 测试无参数函数
TEST_F(FunctionTest, NoParameterFunction) {
    std::string source = R"(
        function GetConstant()
            return 42
        endfunction
        
        let result = GetConstant()
    )";
    
    Value result = execute_source(source);
    
    EXPECT_TRUE(vm.has_global("result"));
    Value result_val = vm.get_global("result");
    EXPECT_TRUE(result_val.is_number());
    EXPECT_EQ(result_val.as_number(), 42.0);
}

// 测试多参数函数
TEST_F(FunctionTest, MultipleParameters) {
    std::string source = R"(
        function Multiply(a, b, c)
            return a * b * c
        endfunction
        
        let result = Multiply(2, 3, 4)
    )";
    
    Value result = execute_source(source);
    
    EXPECT_TRUE(vm.has_global("result"));
    Value result_val = vm.get_global("result");
    EXPECT_TRUE(result_val.is_number());
    EXPECT_EQ(result_val.as_number(), 24.0);
}

// 测试函数中使用局部变量
TEST_F(FunctionTest, LocalVariables) {
    std::string source = R"(
        function Calculate(a, b)
            let sum = a + b
            let product = a * b
            return sum + product
        endfunction
        
        let result = Calculate(3, 4)
    )";
    
    Value result = execute_source(source);
    
    EXPECT_TRUE(vm.has_global("result"));
    Value result_val = vm.get_global("result");
    EXPECT_TRUE(result_val.is_number());
    EXPECT_EQ(result_val.as_number(), 19.0); // (3+4) + (3*4) = 7 + 12 = 19
}

// 测试嵌套函数调用
TEST_F(FunctionTest, NestedFunctionCalls) {
    std::string source = R"(
        function Add(a, b)
            return a + b
        endfunction
        
        function Double(x)
            return x * 2
        endfunction
        
        let result = Double(Add(3, 4))
    )";
    
    Value result = execute_source(source);
    
    EXPECT_TRUE(vm.has_global("result"));
    Value result_val = vm.get_global("result");
    EXPECT_TRUE(result_val.is_number());
    EXPECT_EQ(result_val.as_number(), 14.0); // (3+4) * 2 = 7 * 2 = 14
}

// 测试函数返回不同类型的值
TEST_F(FunctionTest, ReturnDifferentTypes) {
    std::string source = R"(
        function GetString()
            return "hello"
        endfunction
        
        function GetNumber()
            return 123
        endfunction
        
        let str_result = GetString()
        let num_result = GetNumber()
    )";
    
    Value result = execute_source(source);
    
    EXPECT_TRUE(vm.has_global("str_result"));
    Value str_val = vm.get_global("str_result");
    EXPECT_TRUE(str_val.is_string());
    EXPECT_EQ(str_val.as_string(), "hello");
    
    EXPECT_TRUE(vm.has_global("num_result"));
    Value num_val = vm.get_global("num_result");
    EXPECT_TRUE(num_val.is_number());
    EXPECT_EQ(num_val.as_number(), 123.0);
}